﻿using Data;
using Data.Tables;
using PayrollExpress.Helpers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace PayrollExpress.Models
{
    public static class MasterfileHelper
    {
        #region Drop Down Lists

        public static IEnumerable<SelectListItem> GetYearsDropDownList()
        {
            using (var db = new DatabaseContext())
            {
                var years = db.Holidays.Select(s => s.Year).Distinct().ToList();

                if (!years.Contains(DateTime.Now.Year))
                    years.Add(DateTime.Now.Year);

                var yearList = new List<SelectListItem>();

                foreach (var year in years)
                {
                    var item = new SelectListItem();
                    item.Value = year.ToString();
                    item.Text = year.ToString();

                    yearList.Add(item);
                }

                return yearList;
            }
        }

        #endregion

        #region List Titles

        public enum ListTitles
        {
            [Description("Recurring Holidays")]
            RecurringHolidays = 0,
            [Description("New Holidays")]
            NewHolidays = 1
        }

        #endregion

        #region List Headers

        public enum ListHeaders
        {
            #region Employees

            [Description("Employee Code")]
            EmployeeCode,
            [Description("Employee Name")]
            EmployeeName,
            [Description("Address")]
            Address,
            [Description("Current Employment Type")]
            CurrentEmploymentType,
            [Description("Current Rate Type")]
            CurrentRateType,
            [Description("Current Rate")]
            CurrentRate,
            [Description("Work Location")]
            WorkLocation,
            [Description("Is Active")]
            IsActive,

            #endregion

            #region Employee Contract

            [Description("Employment Type")]
            EmploymentType,
            [Description("Rate Type")]
            RateType,
            [Description("Rate")]
            Rate,
            [Description("Start Date")]
            StartDate,
            [Description("End Date")]
            EndDate,
            [Description("Is Current")]
            IsCurrent,

            #endregion

            #region Holidays

            [Description("Year")]
            Year,
            [Description("Date")]
            Date,
            [Description("Day")]
            Day,
            [Description("Description")]
            Description,
            [Description("Holiday Type")]
            HolidayTypeName

            #endregion

        }

        #endregion

        #region Holidays

        public static HolidayListModel GetHolidayListModel(int? year)
        {
            year = year.HasValue ? year : DateTime.Now.Year;

            var model = new HolidayListModel();
            model.Years = GetYearsDropDownList();
            model.ListItems = GetHolidayList(year.GetValueOrDefault());
            return model;
        }

        public static List<HolidayQuery> GetHolidayList(int year)
        {
            var list = new List<HolidayQuery>();

            using (var db = new DatabaseContext())
            {
                var paramYear = new SqlParameter("@Year", year);

                list = db.Database
                    .SqlQuery<HolidayQuery>("sp_GetHolidayList @Year", paramYear)
                    .ToList();
            }

            return list;
        }

        public static HolidaysAddModel GetHolidaysAddModel(DatabaseContext db, int? year)
        {
            year = year.HasValue && year > 0 ? year : DateTime.Now.Year;

            var model = new HolidaysAddModel();

            model.PageAction = BaseHelper.PageAction.Add.ToString();

            model.Year = year.GetValueOrDefault();
            model.CalendarMonths = AdministrationHelper.CalendarMonthDropDownList();
            model.CalendarDays = AdministrationHelper.CalendarDayDropDownList();
            model.HolidayTypes = AdministrationHelper.HolidayTypeDropDownList();

            var recurringHolidays = db.RecurringHolidays.Where(w => w.IsActive == true);
            var recurringHolidayIds = recurringHolidays.Select(s => s.ID);

            var holidaysForYear = db.Holidays.Where(w => w.Year == year).ToList();
            var existingRecurringHolidayIds = holidaysForYear.Select(s => s.RecurringHolidayID);

            var newRecurringHolidays = recurringHolidays.Where(w => !existingRecurringHolidayIds.Contains(w.ID)).Select(s => s).ToList();

            model.NewRecurringHolidays = GetNewRecurringHolidays(newRecurringHolidays, year.GetValueOrDefault());
            model.NewHolidays = GetNewHolidays(year.GetValueOrDefault());

            return model;
        }

        private static List<HolidayQuery> GetNewRecurringHolidays(List<RecurringHoliday> recurringHolidays, int year)
        {
            var list = new List<HolidayQuery>();

            foreach (var item in recurringHolidays)
            {
                var holiday = new HolidayQuery();

                holiday.Month = item.Month;
                holiday.Day = item.Day;
                holiday.Year = year;
                holiday.Description = item.Description;
                holiday.HolidayTypeID = item.HolidayTypeID;
                holiday.HolidayTypeName = ((AdministrationHelper.HolidayType)item.HolidayTypeID).ToDescription();
                holiday.RecurringHolidayID = item.ID;

                if (item.Month > 0 && item.Day > 0)
                    holiday.Date = new DateTime(year, item.Month, item.Day);

                list.Add(holiday);
            }

            return list;
        }

        private static List<HolidayQuery> GetNewHolidays(int year)
        {
            var list = new List<HolidayQuery>();

            for (int i = 1; i <= 5; i++)
            {
                var holiday = new HolidayQuery();

                holiday.Month = 0;
                holiday.Day = 0;
                holiday.Year = year;
                holiday.Description = string.Empty;
                holiday.HolidayTypeID = 0;
                holiday.HolidayTypeName = string.Empty;
                holiday.RecurringHolidayID = null;
                holiday.Date = null;

                list.Add(holiday);
            }

            return list;
        }

        public static HolidayEditModel GetHolidayEditModel(DatabaseContext db, int? id)
        {
            if (!id.HasValue) return null;

            var model = new HolidayEditModel();
            model.PageAction = BaseHelper.PageAction.Edit.ToString();

            model.CalendarMonths = AdministrationHelper.CalendarMonthDropDownList();
            model.CalendarDays = AdministrationHelper.CalendarDayDropDownList();
            model.HolidayTypes = AdministrationHelper.HolidayTypeDropDownList();

            model.Type = db.Holidays.Where(w => w.ID == id).SingleOrDefault<Holiday>();
            model.Date = new DateTime(model.Type.Year, model.Type.Month, model.Type.Day);

            return model;
        }

        #endregion

        #region Employees

        public static EmployeeListModel GetEmployeeListModel(DatabaseContext db, string userName, int? workLocationID)
        {
            workLocationID = workLocationID.HasValue && workLocationID > 0 ? workLocationID : AdministrationHelper.GetUserWorkLocationID(db, userName);
            
            var model = new EmployeeListModel();

            model.SelectedWorkLocationID = workLocationID.GetValueOrDefault();
            model.WorkLocations = AdministrationHelper.WorkLocationDropDownList();
            model.ListItems = GetEmployeeList(workLocationID.GetValueOrDefault());
            
            return model;
        }

        public static List<EmployeeQuery> GetEmployeeList(int workLocationID, bool excludeInactive = false)
        {
            var list = new List<EmployeeQuery>();

            using (var db = new DatabaseContext())
            {
                var paramWorkLocationID = new SqlParameter("@WorkLocationID", workLocationID);
                var paramExcludeInactive = new SqlParameter("@ExcludeInactive", excludeInactive);

                list = db.Database
                    .SqlQuery<EmployeeQuery>("sp_GetEmployeeList @WorkLocationID, @ExcludeInactive", paramWorkLocationID, paramExcludeInactive)
                    .ToList();
            }

            return list;
        }

        public static EmployeeAddEditModel GetEmployeeAddEditModel(DatabaseContext db, int workLocationID, string employeeCode = "")
        {
            var model = new EmployeeAddEditModel();

            model.WorkLocations = AdministrationHelper.WorkLocationDropDownList();

            if (string.IsNullOrEmpty(employeeCode))
            {
                model.PageAction = BaseHelper.PageAction.Add.ToString();

                model.Type = new Employee();
                model.Type.EmployeeCode = string.Empty;
                model.Type.FirstName = string.Empty;
                model.Type.MiddleName = string.Empty;
                model.Type.LastName = string.Empty;
                model.Type.Address = string.Empty;
                model.Type.WorkLocationID = workLocationID;
                model.Type.IsActive = true;
                model.IsActiveYesNo = true.ToYesNoString();
            }
            else
            {
                model.PageAction = BaseHelper.PageAction.Edit.ToString();

                var type = db.Employees.Where(w => w.EmployeeCode == employeeCode).SingleOrDefault<Employee>();
                model.Type = type;
                model.IsActiveYesNo = type.IsActive.ToYesNoString();
            }

            return model;
        }

        public static string GetEmployeeName(string employeeCode)
        {
            Employee employee;
            var name = string.Empty;

            var list = new DatabaseContext().Employees.Where(w => w.EmployeeCode == employeeCode);

            if (list.Any())
            {
                employee = list.SingleOrDefault<Employee>();
                name = string.Format("{0}, {1} {2}", employee.LastName, employee.FirstName, employee.MiddleName);
            }

            return name;
        }

        #endregion

        #region Employee Contracts

        public static EmployeeContractListModel GetEmployeeContractListModel(string employeeCode)
        {
            var model = new EmployeeContractListModel();
            model.EmployeeCode = employeeCode;
            model.EmployeeName = GetEmployeeName(employeeCode);
            model.ListItems = GetEmployeeContractList(employeeCode);
            return model;
        }

        public static List<EmployeeContractQuery> GetEmployeeContractList(string employeeCode)
        {
            var list = new List<EmployeeContractQuery>();

            using (var db = new DatabaseContext())
            {
                var paramEmployeeCode= new SqlParameter("@EmployeeCode", employeeCode);

                list = db.Database
                    .SqlQuery<EmployeeContractQuery>("sp_GetEmployeeContractList @EmployeeCode", paramEmployeeCode)
                    .ToList();
            }

            return list;
        }

        public static EmployeeContractAddEditModel GetEmployeeContractAddEditModel(DatabaseContext db, string employeeCode, int? id = null)
        {
            var model = new EmployeeContractAddEditModel();

            model.EmployeeCode = employeeCode;
            model.EmployeeName = GetEmployeeName(employeeCode);
            model.EmploymentTypes = AdministrationHelper.EmploymentTypeDropDownList();
            model.RateTypes = AdministrationHelper.RateTypeDropDownList();

            if (id == null)
            {
                model.PageAction = BaseHelper.PageAction.Add.ToString();
                model.Type = new EmployeeContract();

                model.Type.EmployeeCode = employeeCode;
                model.Type.EmploymentTypeID = 0;
                model.Type.RateTypeID = 0;
                model.Type.Rate = 0;
                model.Type.StartDate = DateTime.Today;
                model.Type.IsCurrent = true;
            }
            else
            {
                model.PageAction = BaseHelper.PageAction.Edit.ToString();
                model.Type = db.EmployeeContracts.Where(w => w.ID == id).SingleOrDefault<EmployeeContract>();
            }

            return model;
        }
        
        #endregion

    }
}